﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Configuration;
using System.Linq;
using System.Net.Mime;
using System.Reflection;
using System.Runtime.Remoting.Contexts;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using yao.Common;
using yao.website.Controllers;
using Titan;
using Titan.MySql;
using Titan.SqlTracer;
using System.IO;

namespace yao.website
{
    public class BaseController : Controller
    {

        public static ISqlProvider SqlProvider;
        public static ISqlTracer[] SqlTracers;

        protected ApplicationTypeEnum ApplicationType
        {
            get
            {
                if (Request.Headers["ApplicationType"] == null)
                {
                    return ApplicationTypeEnum.Web;
                }
                if (Request.Headers["ApplicationType"].Equals(((int)ApplicationTypeEnum.App).ToString()))
                {
                    return ApplicationTypeEnum.App;
                }
                return ApplicationTypeEnum.Web;
            }
        }

        public BaseController()
            : base()
        {
            #region 表单验证
            //移除mvc 默认的验证机制
            ModelValidatorProviders.Providers.Clear(); 
          
            //存储表单验证的错误信息
            ViewData["BusinessPageError"] = new List<string>();
            #endregion

            SqlProvider = new MySqlSqlProvider();
            FileSqlTracer tracer = new FileSqlTracer();
            tracer.FileName =Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"sqllog\\{yyyyMMdd_HH}.txt");
            SqlTracers = new ISqlTracer[] { tracer };
        
        }

        public static string ConnectionString
        {
            get
            {
                if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["ConnectionString"]))
                {
                    throw new BusinessException("请先配置数据库");
                }
                return ConfigurationManager.AppSettings["ConnectionString"];
            }
        }

        /// <summary>
        /// 注意没有登录的时候，返回的是null
        /// </summary>
        public CurrentEmployee CurrentEmployee
        {
            get
            {
                return Request.GetCookieValue<CurrentEmployee>("_e");
            }
        }

        #region View
        protected new ActionResult View()
        {
            if (ApplicationType == ApplicationTypeEnum.App)
            {
                if (IsValid)
                {
                    return Json(null);
                }
                return GetError();
            }
            return base.View();
        }

        protected new ActionResult View(IView view)
        {
            if (ApplicationType == ApplicationTypeEnum.App)
            {
                if (IsValid)
                {
                    return Json(null);
                }
                return GetError();
            }
            return base.View(view);
        }

        protected new ActionResult View(object model)
        {
            if (ApplicationType == ApplicationTypeEnum.App)
            {
                if (IsValid)
                {
                    return Json(model);
                }
                return GetError();
            }
            return base.View(model);
        }

        protected new ActionResult View(string viewName)
        {
            if (ApplicationType == ApplicationTypeEnum.App)
            {
                if (IsValid)
                {
                    return Json(null);
                }
                return GetError();
            }
            return base.View(viewName);
        }

        protected new ActionResult View(IView view, object model)
        {
            if (ApplicationType == ApplicationTypeEnum.App)
            {
                if (IsValid)
                {
                    return Json(model);
                }
                return GetError();
            }
            return base.View(view, model);
        }


        protected new ActionResult View(string viewName, object model)
        {
            if (ApplicationType == ApplicationTypeEnum.App)
            {
                if (IsValid)
                {
                    return Json(model);
                }
                return GetError();
            }
            return base.View(viewName, model);
        }

        protected new ActionResult View(string viewName, string masterName)
        {
            if (!string.IsNullOrEmpty(Request.Headers["ApplicationType"]))
            {
                return Json(null);
            }
            return base.View(viewName, masterName);
        }
        protected new ActionResult View(string viewName, string masterName, object model)
        {
            if (!string.IsNullOrEmpty(Request.Headers["ApplicationType"]))
            {
                return Json(model);
            }
            return base.View(viewName, masterName, model);
        }
        #endregion

        #region 表单验证
        protected void Validate(object model, params string[] propertyNames)
        {
            Type type = model.GetType();
            foreach (string propertyName in propertyNames)
            {
                PropertyInfo propertyInfo = type.GetProperty(propertyName);
                object propertyValue = propertyInfo.GetValue(model);
                foreach (ValidationAttribute attribute in propertyInfo.GetCustomAttributes().OfType<ValidationAttribute>())
                {
                    if (!attribute.IsValid(propertyValue))
                    {
                        ModelState.AddModelError(propertyName, attribute.ErrorMessage);
                    }
                }
            }
        }
        protected void Validate(object model, params PropertyExpression[] propertyExpressions)
        {
            Type type = model.GetType();
            foreach (PropertyExpression propertyExpression in propertyExpressions)
            {
                string propertyName = propertyExpression.PropertyName;
                PropertyInfo propertyInfo = type.GetProperty(propertyName);
                object propertyValue = propertyInfo.GetValue(model);
                foreach (ValidationAttribute attribute in propertyInfo.GetCustomAttributes().OfType<ValidationAttribute>())
                {
                    if (!attribute.IsValid(propertyValue))
                    {
                        ModelState.AddModelError(propertyName, attribute.ErrorMessage);
                    }
                }
            }
        }

        public void AddPageError(string message)
        {
            ((List<string>)ViewData["BusinessPageError"]).Add(message);
        }
        public void AddFormError(PropertyExpression name, string message)
        {
            //AddFormError(name.PropertyName, message);
            ModelState.AddModelError(name.PropertyName, message);
        }
        public void AddFormError(string name, string message)
        {
            ModelState.AddModelError(name, message);
        }
        protected bool IsValid
        {
            get
            {
                return ((List<string>)ViewData["BusinessPageError"]).Count <= 0  &&
                    ModelState.IsValid;
            }
        }

        private JsonResult GetError()
        {
            if (IsValid)
            {
                return null;
            }
            Dictionary<string, object> dic = new Dictionary<string,object>();
            
            foreach (var d in ModelState)
            {
                dic.Add(d.Key, d.Value);
            }
            foreach (var l in (List<string>)ViewData["BusinessPageError"])
            {
                dic.Add("PageError", l);
            }
            return Json(new
            {
                error = dic
            });
        }

        /// <summary>
        /// 验证字符串是否为null 或者空
        /// </summary>
        /// <param name="name"></param>
        /// <param name="str"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        protected virtual void LIsNullEmpty(string name, string str, string message)
        {
            if (string.IsNullOrEmpty(str))
            {
                AddFormError(name, message);
            }
        }
        /// <summary>
        /// 比较两个字符串是否相同
        /// </summary>
        /// <param name="name"></param>
        /// <param name="str1"></param>
        /// <param name="str2"></param>
        /// <param name="message"></param>
        protected virtual void LStrEquals(string name, string str1, string str2, string message)
        {
            if (!string.Equals(str1, str2))
            {
                AddFormError(name, message);
            }
        }
        /// <summary>
        ///字符串最大长度
        /// </summary>
        /// <param name="name"></param>
        /// <param name="str"></param>
        /// <param name="message"></param>
        protected virtual void LMaxLength(string name, string str, string message)
        {

        }
        /// <summary>
        /// 字符串最小长度
        /// </summary>
        /// <param name="name"></param>
        /// <param name="str"></param>
        /// <param name="message"></param>
        protected virtual void LMinLength(string name, string str, string message)
        {

        }

        #endregion

        #region
        protected IDbSession OpenSession()
        {
            IDbSession session = new DbSession(SqlProvider, ConnectionString, SqlTracers);
            session.Open();
            return session;
        }
        #endregion

        public void SetLedinghuoSystemCode(LedinghuoSystemCodeEnum ledinghuoSystemCode)
        {
            ViewData["LedinghuoSystemCode"] = ledinghuoSystemCode;
        }

        protected override void OnActionExecuting(ActionExecutingContext context)
        {
            base.OnActionExecuting(context);

            if (context.Controller.GetType() == typeof(LoginController) ||
                  context.Controller.GetType() == typeof(RegistController))
            {
                //碰到这两个控制器就不需要拦截，直接退出
                return;
            }


            bool isNeedLogin = CurrentEmployee == null;

            if (!isNeedLogin && 
                (Request.GetCookieString("_e") + CommonFun.GetIpAddress()).GetHashCode().ToString() !=
                Request.GetCookieValue("_k")
                )
            {
                isNeedLogin = true;
            }


            if (!isNeedLogin)
            {
                string loginer = SSOHelper.GetLoginer(CurrentEmployee.EmployeeId.ToString());
                if (string.IsNullOrEmpty(loginer))
                {
                    isNeedLogin = true;
                }
                if (loginer != Request.GetCookieString("_o"))
                {
                    SetLedinghuoSystemCode(LedinghuoSystemCodeEnum.Remotelogin);
                    isNeedLogin = false;
                    //Response.RemoveCookie("_e");
                    //Response.RemoveCookie("_k");
                    //Response.RemoveCookie("_o");
                    //throw new BusinessException("你的帐号已在其他地方登录");
                }
            }


            if (isNeedLogin)
            {
                Response.RemoveCookie("_e");
                Response.RemoveCookie("_k");
                Response.RemoveCookie("_o");
                //设置登录成功后转向的URL，格式例如:http://xxx.xxx/login.aspx?u=www.baidu.cn
                string returnUrl = string.Format("?u={0}", Server.UrlEncode(Request.Url.AbsoluteUri));
                //重定向到登录的URL后面的returnUrl参数用于登录通过后的页面跳转
                string loginUrl = Url.Action("Index", "Login") + returnUrl;
                //Response.Redirect(loginUrl);
                context.Result = new RedirectResult(loginUrl);
            }
        }

        #region ajax 返回值
        protected JsonResult LJson(bool ret,string message) {
            return Json(new { ret = ret, message = message });
        }
        protected JsonResult LJson(object data)
        {
            return Json(data);
        }
        #endregion
    }
}
